package com.atguigu.ssyx.product.service.impl;

import com.atguigu.ssyx.product.config.MinioConfig;
import com.atguigu.ssyx.product.service.FileUploadService;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
 * @作者:胡树苑
 * @时间:2025/9/13 19:41
 */
@Service
public class FileUploadServiceImpl implements FileUploadService {
    @Autowired
    private MinioClient minioClient;
    @Autowired
    private MinioConfig minioConfig;

    @PostConstruct
    public void setBucketPolicy() {
        try {
            String policy = "{\n" +
                    "  \"Version\": \"2012-10-17\",\n" +
                    "  \"Statement\": [\n" +
                    "    {\n" +
                    "      \"Effect\": \"Allow\",\n" +
                    "      \"Principal\": \"*\",\n" +
                    "      \"Action\": \"s3:GetObject\",\n" +
                    "      \"Resource\": \"arn:aws:s3:::" + minioConfig.getBucket() + "/*\"\n" +
                    "    }\n" +
                    "  ]\n" +
                    "}";

            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder()
                            .bucket(minioConfig.getBucket())
                            .config(policy)
                            .build()
            );
            System.out.println("存储桶策略设置成功");
        } catch (Exception e) {
            System.err.println("设置存储桶策略失败: " + e.getMessage());
        }
    }

    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        //1.检查存储桶是否存在，不存在则创建
        if(!minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioConfig.getBucket()).build())){
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucket()).build());
        }

        //获取文件实际名称
        String objectName = file.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        objectName = uuid + objectName;
        //对上传的文件进行分组
        //objectName:2023/10/10.jpg
        String currentdatetime = new DateTime().toString("yyyy/MM/dd");
        objectName = currentdatetime +"/"+ objectName;
        //创建上传文件对象
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(minioConfig.getBucket())
                        .object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())//文件类型 比如image/jpeg
                        .build());
        objectName=getUrl(objectName);
        return objectName;
    }

    @Override
    public String uploadFile(MultipartFile file, String folder) throws Exception {
        //1.检查存储桶是否存在，不存在则创建
        if(!minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioConfig.getBucket()).build())){
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioConfig.getBucket()).build());
        }
        //2.生成唯一文件名(避免重命名)
        String originalFilename = file.getOriginalFilename();//example.txt
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = UUID.randomUUID().toString() + fileExtension;

        //3.构建完整的对象路径（包含文件夹）
        String objectName;
        if (folder != null && !folder.trim().isEmpty()) {
            // 确保文件夹路径以/结尾
            String normalizedFolder = folder.trim();
            if (!normalizedFolder.endsWith("/")) {
                normalizedFolder += "/";
            }
            objectName = normalizedFolder + newFileName;
        } else {
            objectName = newFileName;
        }

        //4.上传文件
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(minioConfig.getBucket())
                        .object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .contentType(file.getContentType())//文件类型 比如image/jpeg
                        .build());
        objectName=getUrl(objectName);
        return objectName; // 返回完整路径
    }

    @Override
    public String getUrl(String newFileName) throws Exception {
        // 如果newFileName不包含路径，说明只是文件名，需要查找完整路径
        if (!newFileName.contains("/")) {
            // 查找文件（支持模糊匹配）
            Iterable<Result<Item>> results = minioClient.listObjects(
                    ListObjectsArgs.builder()
                            .bucket(minioConfig.getBucket())
                            .recursive(true)
                            .build()
            );

            for (Result<Item> result : results) {
                Item item = result.get();
                String objectName = item.objectName();
                if (objectName.endsWith(newFileName)) {
                    return minioConfig.getEndpoint() + "/" + minioConfig.getBucket() + "/" + objectName;
                }
            }
            throw new Exception("文件未找到: " + newFileName);
        }

        // 如果newFileName包含完整路径，直接返回
        return minioConfig.getEndpoint() + "/" + minioConfig.getBucket() + "/" + newFileName;
    }
}